home *** CD-ROM | disk | FTP | other *** search
/ Atari Forever 4 / Atari Forever 4.zip / Atari Forever 4.iso / SERIE_AI / AI_027 / CFAT_R3.LZH / archive.lzh / autocfat.c next >
C/C++ Source or Header  |  1996-03-10  |  20KB  |  677 lines

  1. /*3456789012345678901234567890123456789012345678*/
  2. /*
  3.  * autocfat.c vom 10.03.1996
  4.  *
  5.  * Autor:
  6.  * Thomas Binder
  7.  * (binder@rbg.informatik.th-darmstadt.de)
  8.  *
  9.  * Zweck:
  10.  * Programm für den Auto-Ordner, das CheckFat der
  11.  * Reihe nach für bestimmte Laufwerke aufruft und
  12.  * bei fehlerhafter FAT einen zweiten Test mit
  13.  * erweiterten Parametern ermöglicht.
  14.  *
  15.  * Vielen Dank auch an meine Betatester (in alpha-
  16.  * betischer Reihenfolge):
  17.  * Alexander Clauss, Dirk Klemmt, Rainer Riedl,
  18.  * Michael Schwingen, Uwe Seimet, Manfred Ssykor
  19.  * und Arno Welzel.
  20.  *
  21.  * History:
  22.  * 29.03.1995: Erstellung
  23.  * 02.04.1995: Änderung der Abbruchbedingung bei
  24.  *             Programmstart: CheckFat wird nicht
  25.  *             aufgerufen, wenn keine Sondertaste
  26.  *             gedrückt ist. Man muß also zum
  27.  *             Test explizit Shift o.ä. drücken,
  28.  *             weil ein Test bei jedem Warmstart
  29.  *             doch etwas nervig ist. Wer es doch
  30.  *             andersherum möchte, braucht nur die
  31.  *             anfängliche Abfrage zu negieren.
  32.  * 12.04.1995: CheckFat-Pfad ist jetzt c:\bin
  33.  * 21.07.1995: AutoCFat wertet jetzt eine Datei
  34.  *             AUTOCFAT.INF aus, die im Auto-
  35.  *             Ordner oder im Wurzelverzeichnis
  36.  *             des Bootlaufwerks liegen darf. Die
  37.  *             erste Zeile enthält den Pfad für
  38.  *             CheckFat, die zweite die Laufwerke,
  39.  *             die überprüft werden sollen (als
  40.  *             Zeichenkette, also z.B. CDE).
  41.  * 10.08.1995: Falschen Kommentar geändert.
  42.  * 24.08.1995: Anpassung an MiNT-Library
  43.  * 10.10.1995: Anpassung an neue Version von
  44.  *             CheckFat, die jetzt auch mehrfach
  45.  *             belegte Cluster mit Dateinamen
  46.  *             melden kann.
  47.  * 12.10.1995: AutoCFat merkt sich jetzt zu Beginn
  48.  *             das aktuelle Laufwerk und den
  49.  *             aktuellen Pfad und setzt beides
  50.  *             am Schluß wieder. Damit klappt das
  51.  *             Prüfen von C: auch dann, wenn
  52.  *             AutoCFat unter MagiC 3 aus dem
  53.  *             Auto-Ordner von C: gestartet wurde.
  54.  *             (Bisher gab es hier einen Absturz,
  55.  *             weil durch das Dlock von CheckFat
  56.  *             der aktuelle Pfad des Bootlaufwerks
  57.  *             verloren ging, was der Auto-Ordner-
  58.  *             Abarbeitung von MagiC 3 überhaupt
  59.  *             nicht gefällt...)
  60.  * 25.10.1995: AutoCFat sollte, wegen ähnlicher
  61.  *             Probleme wie mit MagiC, immer _vor_
  62.  *             MiNT im Auto-Ordner stehen.
  63.  *             Anpassung an neue Option -d von
  64.  *             CheckFat.
  65.  * 29.10.1995: Damit es keine Probleme mehr mit
  66.  *             MiNT und anderen Betriebssystemen,
  67.  *             die Dlock zur Verfügung stellen,
  68.  *             gibt, ruft AutoCFat CheckFat für
  69.  *             das aktuelle Laufwerk mit der neuen
  70.  *             Option -u auf, die die Benutzung
  71.  *             von Dlock abschaltet. Ernsthaftere
  72.  *             Probleme sind dadurch nicht zu
  73.  *             erwarten, da AutoCFat ja im Auto-
  74.  *             Ordner läuft (bzw. laufen sollte),
  75.  *             und zu der Zeit ist in der Regel
  76.  *             noch kein Multitasking aktiv. Die
  77.  *             beste Lösung ist es ohnehin, das
  78.  *             Programm möglichst weit an den
  79.  *             Anfang des Auto-Ordners zu setzen.
  80.  * 30.10.1995: In der dritten Zeile der INF-Datei
  81.  *             wird jetzt festgelegt, ob eine der
  82.  *             Umschalttasten AutoCFat aktiviert
  83.  *             oder das Prüfen verhindert. Bisher
  84.  *             war das nur im Source zu ändern.
  85.  *             Die alte INF-Datei muß daher auf
  86.  *             jeden Fall angepaßt werden!
  87.  * 12.12.1995: Die dritte Zeile wurde erweitert.
  88.  *             Es kann jetzt festgelegt werden,
  89.  *             welche Sondertasten geprüft werden,
  90.  *             ob diese einzeln oder zusammen
  91.  *             gedrückt sein müssen und ob
  92.  *             AutoCFat nur bei einem Kaltstart
  93.  *             aktiv werden soll.
  94.  *             Bei Fehlern in der INF-Datei werden
  95.  *             jetzt etwas genauere Fehler
  96.  *             gemeldet.
  97.  * 18.12.1995: Dummerweise war die Auswertung des
  98.  *             TUBS-Cookies in is_cold_boot genau
  99.  *             falsch herum... Jetzt tut's.
  100.  * 19.12.1995: Die Reihenfolge der Abbruchs-
  101.  *             Abfrage vertauscht, damit jetzt auf
  102.  *             jeden Fall auf Kaltstart getestet
  103.  *             wird. Bisher ging AutoCFat nämlich
  104.  *             von einem Kaltstart aus, wenn es
  105.  *             zuvor immer per Hotkey am Start
  106.  *             gehindert wurde.
  107.  * 15.01.1996: Letzte Vorbereitungen für die
  108.  *             Veröffentlichung, darunter auch
  109.  *             verbessertes Verhalten, wenn
  110.  *             CheckFat nicht korrekt aufgerufen
  111.  *             werden konnte (z.B. durch falschen
  112.  *             Pfad in der INF-Datei).
  113.  * 18.02.1996: CheckFat wird jetzt immer mit -s
  114.  *             aufgerufen, damit der Bildschirm
  115.  *             nicht mehr mit "wertlosen" Ausgaben
  116.  *             gefüllt wird.
  117.  *             Liefert CheckFat 1 zurück (Prüfung
  118.  *             unvollständig), erhält man jetzt
  119.  *             die Möglichkeit, den Vorgang zu
  120.  *             wiederholen. Gleiches gilt für dem
  121.  *             Programm unbekannte Returncodes.
  122.  * 26.02.1996: Wesentlich schnelleres Einlesen der
  123.  *             INF-Datei (merkt man natürlich nur
  124.  *             dann, wenn sie viele Kommentare
  125.  *             enthält). Außerdem fällt jetzt die
  126.  *             Einschränkung weg, daß die letzte
  127.  *             auszuwertende Zeile ein richtiges
  128.  *             Zeilenende haben muß.
  129.  * 05.03.1996: Unterstützung der neuen Option -1
  130.  *             von CheckFat bei fehlerhafter FAT.
  131.  * 10.03.1996: Wenn CheckFat nicht 0 geliefert
  132.  *             hat, wird die Meldung nicht mehr
  133.  *             versehentlich über die zuletzt von
  134.  *             CheckFat ausgegebene Zeile
  135.  *             geschrieben.
  136.  */
  137.  
  138. #include <mintbind.h>
  139. #include <portab.h>
  140.  
  141. /* Defines für die Sondertasten */
  142. #define RSHIFT  1
  143. #define LSHIFT  2
  144. #define CTRL    4
  145. #define ALT     8
  146. #define CLOCK   16
  147.  
  148. /*
  149.  * In diesem Char-Array stehen alle zu prüfenden
  150.  * Laufwerke (wird aus AUTOCFAT.INF gelesen)
  151.  */
  152. char    to_check[256];
  153.  
  154. /* Pfad von CheckFat, auch aus AUTOCFAT.INF */
  155. char    cfpath[256];
  156.  
  157. /* Puffer für die Zeile zum Hotkey-Verhalten */
  158. char    hotkey[256];
  159.  
  160. /* Prototypen */
  161. WORD readline(WORD handle, char *buffer);
  162. WORD is_cold_boot(void);
  163. WORD get_cookie(ULONG cookie, ULONG *value);
  164.  
  165. WORD main(void)
  166. {
  167.     WORD    result,
  168.             i,
  169.             handle,
  170.             skip_with_hotkey,
  171.             needed,
  172.             possible,
  173.             only_cold,
  174.             hotkey_ok,
  175.             pos,
  176.             names,
  177.             actdrv,
  178.             cluster = 1,
  179.             crosslinks = 0,
  180.             marked = 0,
  181.             fat1 = 0,
  182.             longnames = 0;
  183.     LONG    err;
  184.     char    cline[11],
  185.             *hot,
  186.             *check,
  187.             actpath[256];
  188.  
  189. /* Versuchen, das INF-File zu öffnen */
  190.     if (((handle = (WORD)
  191.         Fopen("\\auto\\autocfat.inf", 0)) < 0) &&
  192.         ((handle = (WORD)
  193.         Fopen("\\autocfat.inf", 0)) < 0))
  194.     {
  195.         Cconws("\r\nKann AUTOCFAT.INF nicht "
  196.             "öffnen!\r\n");
  197.         return(1);
  198.     }
  199. /*
  200.  * INF-Datei ist vorhanden, jetzt die erste Zeile
  201.  * einlesen, die keine Kommentarzeile ist. Gibt es
  202.  * sie nicht, mit einer Fehlermeldung abbrechen.
  203.  */
  204.     if (!readline(handle, cfpath) || !*cfpath)
  205.     {
  206.         Cconws("\r\n1. Zeile von AUTOCFAT.INF "
  207.             "leer!\r\n");
  208.         Fclose(handle);
  209.         return(1);
  210.     }
  211. /*
  212.  * Jetzt die zweite Zeile mit den zu prüfenden
  213.  * Laufwerken lesen; auch hier abbrechen, wenn sie
  214.  * nicht vorhanden ist.
  215.  */
  216.     if (!readline(handle, to_check) || !*to_check)
  217.     {
  218.         Cconws("\r\n2. Zeile von AUTOCFAT.INF "
  219.             "leer!\r\n");
  220.         Fclose(handle);
  221.         return(1);
  222.     }
  223. /*
  224.  * Jetzt noch die Zeile einlesen, die entscheidet,
  225.  * wann AutoCFat prüft oder nicht.
  226.  */
  227.     if (!readline(handle, hotkey))
  228.     {
  229.         Cconws("\r\n3. Zeile von AUTOCFAT.INF "
  230.             "fehlt!\r\n");
  231.         Fclose(handle);
  232.         return(1);
  233.     }
  234.     Fclose(handle);
  235.     only_cold = needed = possible = 0;
  236.     if ((*hotkey != '+') && (*hotkey != '-'))
  237.     {
  238.         Cconws("\r\n3. Zeile von AUTOCFAT.INF "
  239.             "fehlerhaft!\r\n");
  240.         return(1);
  241.     }
  242.     hot = hotkey;
  243.     skip_with_hotkey = (*hot++ == '+');
  244.     for (; *hot; hot++)
  245.     {
  246.         switch (*hot)
  247.         {
  248.             case '+':
  249.                 only_cold = 1;
  250.                 break;
  251.             case 'a':
  252.                 possible |= ALT;
  253.                 break;
  254.             case 'A':
  255.                 needed |= ALT;
  256.                 break;
  257.             case 'c':
  258.                 possible |= CTRL;
  259.                 break;
  260.             case 'C':
  261.                 needed |= CTRL;
  262.                 break;
  263.             case 'l':
  264.                 possible |= LSHIFT;
  265.                 break;
  266.             case 'L':
  267.                 needed |= LSHIFT;
  268.                 break;
  269.             case 'r':
  270.                 possible |= RSHIFT;
  271.                 break;
  272.             case 'R':
  273.                 needed |= RSHIFT;
  274.                 break;
  275.             case 'k':
  276.                 possible |= CLOCK;
  277.                 break;
  278.             case 'K':
  279.                 needed |= CLOCK;
  280.                 break;
  281.             default:
  282.                 hot[1] = 0;
  283.                 break;
  284.         }
  285.         if (only_cold)
  286.         {
  287.             hot++;
  288.             break;
  289.         }
  290.     }
  291.     if ((needed & possible) != 0)
  292.     {
  293.         Cconws("\r\n3. Zeile von AUTOCFAT.INF "
  294.             "fehlerhaft!\r\n");
  295.         return(1);
  296.     }
  297.     if ((needed | possible) == 0)
  298.         possible = 31;
  299.     if (!needed)
  300.         needed = 32;
  301. /*
  302.  * Die INF-Datei wurde erfolgreich gelesen, jetzt
  303.  * das Programm beenden, wenn keine Sondertaste
  304.  * gedrückt ist. Ist skip_with_hotkey ungleich
  305.  * Null (dritte Zeile der INF-Datei enthält '+'),
  306.  * wird das Verhalten umgedreht, d.h. AutoCFat
  307.  * wird verlassen, wenn eine Sondertaste gedrückt
  308.  * ist. Dabei wird natürlich beachtet, welche
  309.  * der Sondertasten zwingend nötig sind und welche
  310.  * auch gedrückt sein dürfen.
  311.  * Ist Prüfung nur bei Kaltstart gewünscht, wird
  312.  * AutoCFat bei Warmstart ebenso beendet.
  313.  */
  314.     if ((((Kbshift(-1) & 31) & needed) == needed)
  315.         || (((Kbshift(-1) & 31) & possible) != 0))
  316.     {
  317.         hotkey_ok = 1;
  318.     }
  319.     else
  320.         hotkey_ok = 0;
  321.     if ((!is_cold_boot() && only_cold) ||
  322.         (skip_with_hotkey == hotkey_ok))
  323.     {
  324.         Cconws("\r\nKeine FATs geprüft!\r\n");
  325.         return(0);
  326.     }
  327. /*
  328.  * INF-Datei wurde erfolgreich gelesen. Jetzt das
  329.  * aktuelle Laufwerk und den aktuellen Pfad
  330.  * sichern und CheckFat für die gewünschten
  331.  * Laufwerke aufrufen.
  332.  */
  333.     actdrv = Dgetdrv();
  334.     Dgetpath(actpath, actdrv + 1);
  335.     Cconws("\r\n");
  336.     for (check = to_check; *check; check++)
  337.     {
  338. check_it:
  339.         Cconws("FAT-Prüfung Laufwerk ");
  340.         Cconout(*check & ~32);
  341.         Cconws("...\r\n");
  342.         pos = 1;
  343.         cline[pos++] = '-';
  344.         cline[pos++] = 's';
  345.         if ((char)(actdrv + 65) == (*check & ~32))
  346.             cline[pos++] = 'u';
  347.         cline[pos++] = ' ';
  348.         cline[pos] = *check;
  349.         cline[0] = pos;
  350.         cline[++pos] = 0;
  351.         err = Pexec(0, cfpath, cline, 0L);
  352.         if (err < 0L)
  353.         {
  354.             Cconws("Fehler beim Aufruf von "
  355.                 "CheckFat!\r\n");
  356.             return(1);
  357.         }
  358.         result = (WORD)err;
  359.         if (result != 3)
  360.         {
  361. /*
  362.  * Neuen Versuch ermöglichen, wenn der Returncode
  363.  * weder Null noch Drei ist
  364.  */
  365.             if (result)
  366.             {
  367.                 if (result == 1)
  368.                 {
  369.                     Cconws("Prüfung "
  370.                         "unvollständig!\r\n");
  371.                 }
  372.                 else
  373.                 {
  374.                     Cconws("Unbekannter"
  375.                         "\r\nRückgabewert!");
  376.                 }
  377.                 Cconws("Neuer Versuch? [j/n] ");
  378.                 if (((WORD)Cconin() & ~32) != 'J')
  379.                 {
  380.                     Cconws("\r\n");
  381.                     continue;
  382.                 }
  383.                 Cconws("\r\n");
  384.                 goto check_it;
  385.             }
  386. /*
  387.  * Hat CheckFat 0 geliefert, war die FAT OK. Also
  388.  * ab zum nächsten zu prüfenden Laufwerk.
  389.  */
  390.                Cconws("\033A");
  391.                for (i = 0; i < 26; i++)
  392.                    Cconws("\033C");
  393.             Cconws("OK\r\n");
  394.             continue;
  395.         }
  396. /*
  397.  * Liefert CheckFat 3 zurück (FAT ist fehlerhaft),
  398.  * einen erneuten Lauf mit erweiterter Ausgabe
  399.  * ermöglichen
  400.  */
  401.         Cconws("FAT ist nicht OK! ");
  402.         Cconws("Mehr Details? [j/n] ");
  403.         if (((WORD)Cconin() & ~32) != 'J')
  404.         {
  405.             Cconws("\r\n");
  406.             continue;
  407.         }
  408.         Cconws("\r\nCluster anzeigen? [j/n] ");
  409.         if (((WORD)Cconin() & ~32) != 'J')
  410.         {
  411.             cluster = 0;
  412.             Cconws("\r\nNamen anzeigen? [j/n] ");
  413.             names = (((WORD)Cconin() & ~32) == 
  414.                 'J');
  415.         }
  416.         Cconws("\r\nMehrfach belegte Cluster "
  417.             "ausführlich\r\nmelden? [j/n] ");
  418.         if (((WORD)Cconin() & ~32) == 'J')
  419.         {
  420.             crosslinks = 1;
  421.             Cconws("\r\nMit vollen Pfadnamen? "
  422.                 "[j/n] ");
  423.             longnames = (((WORD)Cconin() & ~32) ==
  424.                 'J');
  425.         }
  426.         Cconws("\r\nAls defekt markierte Cluster"
  427.             "\r\nmelden? [j/n] ");
  428.         marked = (((WORD)Cconin() & ~32) == 'J');
  429.         Cconws("\r\nFAT1 als Prüfgrundlage ver-"
  430.             "\r\nwenden? [j/n] ");
  431.         fat1 = (((WORD)Cconin() & ~32) == 'J');
  432.         Cconws("\r\n");
  433.         pos = 1;
  434.         cline[pos++] = '-';
  435.         cline[pos++] = 'v';
  436.         cline[pos++] = 's';
  437.         if (cluster || names)
  438.             cline[pos++] = cluster ? 'c' : 'n';
  439.         if (crosslinks || longnames)
  440.             cline[pos++] = longnames ? 'l' : 'x';
  441.         if (marked)
  442.             cline[pos++] = 'd';
  443.         if (fat1)
  444.             cline[pos++] = '1';
  445.         if ((char)(actdrv + 65) == (*check & ~32))
  446.             cline[pos++] = 'u';
  447.         cline[pos++] = ' ';
  448.         cline[pos] = *check;
  449.         cline[0] = pos;
  450.         cline[++pos] = 0;
  451.         Cconws("Detailprüfung Laufwerk ");
  452.         Cconout(*check & ~32);
  453.         Cconws("...\r\n");
  454.         Pexec(0, cfpath, cline, 0L);
  455.         Cconws("Taste drücken!\r\n");
  456.         Cnecin();
  457.     }
  458. /* Laufwerk und Pfad zurücksetzen */
  459.     Dsetdrv(actdrv);
  460.     Dsetpath(actpath);
  461.     return(0);
  462. }
  463.  
  464. /*
  465.  * readline
  466.  *
  467.  * Liest eine Zeile aus einer GEMDOS-Datei ein,
  468.  * die wahlweise mit CRLF oder nur LF enden darf.
  469.  * Beginnt sie mit einem '#', wird gleich die
  470.  * nächste Zeile eingelesen.
  471.  *
  472.  * Eingabe:
  473.  * handle: Zu benutzendes GEMDOS-Handle
  474.  * buffer: Zeiger auf Zeilenpuffer
  475.  *
  476.  * Rückgabe:
  477.  * 0: Fehler beim Lesen (oder: Zeile zu lang)
  478.  * 1: Alles OK
  479.  */
  480. WORD readline(WORD handle, char *buffer)
  481. {
  482.     WORD    count;
  483.     LONG    fpos,
  484.             add,
  485.             bytes_read;
  486.  
  487.     for (;;)
  488.     {
  489.         fpos = Fseek(0L, handle, 1);
  490.         if (fpos < 0L)
  491.             return(0);
  492.         if ((bytes_read =
  493.                 Fread(handle, 255, buffer)) <= 0L)
  494.         {
  495.             return(0);
  496.         }
  497.         count = 0;
  498.         add = 1L;
  499.         for (;;)
  500.         {
  501.             if (count == bytes_read)
  502.             {
  503.                 add = 0L;
  504.                 break;
  505.             }
  506.             if (buffer[count] == '\n')
  507.                 break;
  508.             if (count == 255)
  509.                 return(0);
  510.             if (buffer[count] == '\t')
  511.                 buffer[count] = ' ';
  512.             count++;
  513.         }
  514.         if (Fseek((LONG)count + fpos + add,
  515.             handle, 0) < 0L)
  516.         {
  517.             return(0);
  518.         }
  519.         if (count)
  520.         {
  521.             if (buffer[count - 1] == '\r')
  522.                 count--;
  523.         }
  524.         buffer[count] = 0;
  525.         if (*buffer != '#')
  526.             break;
  527.     }
  528.     return(1);
  529. }
  530.  
  531. /*
  532.  * is_cold_boot
  533.  *
  534.  * Prüft, ob der Rechner gerade eingeschaltet
  535.  * wurde.
  536.  *
  537.  * Rückgabe:
  538.  * 1: Rechner wurde "kaltgestartet"
  539.  * 0: Rechner wurde schon mindestens einmal
  540.  *    "warmgestartet"
  541.  */
  542. WORD is_cold_boot(void)
  543. {
  544.     ULONG   tubs,
  545.             proc_lives;
  546.     LONG    old_stack;
  547.     WORD    cold;
  548.  
  549. /*
  550.  * Zunächst wird nach dem TUBS-Cookie gesucht. Ist
  551.  * dieser vorhanden, kann das gewünschte Ergebnis
  552.  * hier ausgelesen werden (wenn Bit 0 gesetzt ist,
  553.  * lag ein Warmstart vor).
  554.  */
  555.     if (get_cookie('TUBS', &tubs))
  556.         return((WORD)((tubs & 1) ^ 1));
  557. /*
  558.  * Wenn der Cookie nicht vorhanden war, muß eine
  559.  * etwas unsichere Methode benutzt werden (die
  560.  * TCKJ aus dem TUBS-Paket letztlich auch benutzt,
  561.  * allerdings ist sie deswegen zuverlässiger, weil
  562.  * das Programm einen Resethandler installiert,
  563.  * was AutoCFat natürlich nicht machen soll):
  564.  * Es wird geprüft, ob in proc_lives (0x380) ein
  565.  * bestimmter Wert steht. Wenn ja, ist es ein
  566.  * Warmstart, ansonsten wird von einem Kaltstart
  567.  * ausgegangen und der magische Wert 'CFAT' nach
  568.  * 0x380 geschrieben, um beim nächsten Mal den
  569.  * Warmstart zu erkennen.
  570.  */
  571.     if (Super((void *)1L) == 0L)
  572.         old_stack = Super(0L);
  573.     else
  574.         old_stack = 0L;
  575.     proc_lives = *(ULONG *)0x380;
  576. /*
  577.  * Es wird mit 'CFAT', 'TCKJ' und 0x1234578UL
  578.  * verglichen, da prinzipiell keiner dieser Werte
  579.  * bei einem Kaltstart vorzufinden sein dürfte
  580.  * (0x1234578UL wird bei einer Bomben-Exception
  581.  * nach proc_lives geschrieben).
  582.  */
  583.     if ((proc_lives == 'CFAT') || (proc_lives ==
  584.         'TCKJ') || (proc_lives == 0x12345678UL))
  585.     {
  586.         cold = 0;
  587.     }
  588.     else
  589.     {
  590.         cold = 1;
  591.         *(ULONG *)0x380 = 'CFAT';
  592.     }
  593. #if 0
  594.     *(ULONG *)0x6f0 = proc_lives;
  595.     if (cold)
  596.         Cconws("\r\nKaltstart!\r\n");
  597.     else
  598.         Cconws("\r\nWarmstart!\r\n");
  599. #endif
  600.     if (old_stack)
  601.         Super((void *)old_stack);
  602.     return(cold);
  603. }
  604.  
  605. /*
  606.  * get_cookie
  607.  *
  608.  * Prüft, ob ein bestimmter Cookie vorhanden ist
  609.  * und liefert, wenn gewünscht, dessen Wert.
  610.  *
  611.  * Eingabe:
  612.  * cookie: Zu suchender Cookie (z.B. 'MiNT')
  613.  * value: Zeiger auf einen vorzeichenlosen Long,
  614.  *        in den der Wert des Cookies geschrieben
  615.  *        werden soll. Ist dies nicht gewünscht/
  616.  *        erforderlich, einen Nullzeiger über-
  617.  *        geben.
  618.  *
  619.  * Rückgabe:
  620.  * 0: Cookie nicht vorhanden, value unbeeinflußt
  621.  * 1: Cookie vorhanden, Wert steht in value (wenn
  622.  *    value kein Nullpointer ist)
  623.  */
  624. WORD get_cookie(ULONG cookie, ULONG *value)
  625. {
  626.     LONG    *jar,
  627.             old_stack;
  628.     
  629.     /*
  630.      * Den Zeiger auf den Cookie-Jar ermitteln,
  631.      * dabei ggf. in den Supervisor-Modus
  632.      * wechseln.
  633.      */
  634.     if (Super((void *)1L) == 0L)
  635.     {
  636.         old_stack = Super(0L);
  637.         jar = *((LONG **)0x5a0L);
  638.         Super((void *)old_stack);
  639.     }
  640.     else
  641.         jar = *(LONG **)0x5a0;
  642.     
  643.     /*
  644.      * Ist die "Keksdose" leer, gleich Null zu-
  645.      * rückliefern, da ja gar kein Cookie
  646.      * vorhanden ist.
  647.      */
  648.     if (jar == 0L)
  649.         return(0);
  650.     
  651.     /*
  652.      * Sonst den Cookie-Jar bis zum Ende durch-
  653.      * suchen und im Erfolgsfall 1 zurückliefern.
  654.      * Falls value kein Nullpointer war, vorher
  655.      * den Wert des Cookies dort eintragen.
  656.      */
  657.     while (jar[0])
  658.     {
  659.         if (jar[0] == cookie)
  660.         {
  661.             if (value != 0L)
  662.                 *value = jar[1];
  663.             
  664.             return(1);
  665.         }
  666.         
  667.         jar += 2;
  668.     }
  669.     /*
  670.      * Bis zum Ende gesucht und nichts gefunden,
  671.      * also 0 zurückgeben.
  672.      */
  673.     return(0);
  674. }
  675.  
  676. /* EOF */
  677.